package com.cloud.screen.api.service.impl;

import com.cloud.screen.api.entity.UnitInfo;
import com.cloud.screen.api.mapper.UnitInfoMapper;
import com.cloud.screen.api.service.ForceService;
import com.cloud.screen.common.utils.DateHelper;
import com.cloud.screen.interfaces.FeignClientForce;
import com.cloud.screen.interfaces.FeignClientSystem;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @program: quokka-server
 * @description: ${ForceService}
 * @author: sl
 * @create: 2019-07-04 15:33
 **/
@Service
public class ForceServiceImpl implements ForceService {

    private static final Logger logger = LoggerFactory.getLogger(ForceServiceImpl.class);
    @Autowired
    private FeignClientForce feignClientForce;

    @Autowired
    private FeignClientSystem feignClientSystem;

    @Autowired
    private UnitInfoMapper unitInfoMapper;

    private static final Integer SELECT_HOUR = 1;
    private static final Integer SELECT_WEEK= 3;
    private static final Integer SELECT_QUARTER = 5;
    private static final Integer SELECT_HALFYAER = 6;

    @Override
    public List<Map<String, Object>> getLegalCaseInfo(String start ,String end,Long regionid,Integer type,Integer recType) {
        if (type == null){
            type = 1;
        }
        UnitInfo unit = unitInfoMapper.selectByPrimaryKey(regionid == null?1:regionid);
        List<Map<String, Object>> list = feignClientForce.getRecForceByDate(start,end,unit.getUnitCode(),type,recType);
        if (list != null){
            if (type .equals(SELECT_HOUR)){
                logger.debug("分时查询->分组封装");
                List<String> dateList = DateHelper.getDateList();
                List<String> stringList = new ArrayList<>();
                list.forEach(v->{
                    stringList.add(v.get("timeRange").toString());
                });
                stringList.forEach(c->{
                    dateList.removeIf(s -> s.contains(c));
                });
                List<Map<String, Object>> finalQueryForList = list;
                dateList.forEach(k->{
                    logger.debug("分时查询-封装返回->");
                    Map<String,Object> map = new HashedMap();
                    map.put("count",0);
                    map.put("timeRange",k);
                    finalQueryForList.add(map);
                });
            } else if (type.equals(SELECT_WEEK)){
                list.forEach(v->{
                    v.put("timeRange", DateHelper.getWeekDays(DateHelper.strToDate(v.get("timeRange").toString())));
                });
                list = list.stream().collect(Collectors.groupingBy(e -> e.get("timeRange")))
                        .entrySet().stream().map(e -> {
                            Map<String, Object> map = new HashMap<>();
                            map.put("timeRange", e.getKey());
                            map.put("count", e.getValue().size());
                            return map;
                        }).collect(Collectors.toList());
            } else if (type.equals(SELECT_QUARTER)) {
                Map<String, Map<String, Object>> times = new HashMap<>();
                list.forEach(v -> {
                    String quarter = DateHelper.monthToQuarter(v.get("timeRange").toString());
                    Map<String, Object> item = times.get(quarter);
                    if (item == null) {
                        item = new HashedMap();
                        item.put("timeRange", quarter);
                        item.put("count", 0);
                    }
                    Long count = item.get("count") == null ? 0 : Long.parseLong(item.get("count").toString());
                    count += v.get("count") == null ? 0 : Long.parseLong(v.get("count").toString());
                    item.put("count", count);

                    times.put(quarter, item);
                });
                list = new ArrayList<>(times.values());
            } else if (type.equals(SELECT_HALFYAER)) {
                Map<String, Map<String, Object>> times = new HashMap<>();
                list.forEach(v -> {
                    String half = DateHelper.monthToHalfYear(v.get("timeRange").toString());
                    Map<String, Object> item = times.get(half);
                    if (item == null) {
                        item = new HashedMap();
                        item.put("timeRange", half);
                        item.put("count", 0);
                    }
                    Long count = item.get("count") == null ? 0 : Long.parseLong(item.get("count").toString());
                    count += v.get("count") == null ? 0 : Long.parseLong(v.get("count").toString());
                    item.put("count", count);

                    times.put(half, item);
                });
                list = new ArrayList<>(times.values());
            }
            list.sort(Comparator.comparing(o -> o.get("timeRange").toString()));
        }
        return list;
    }

    @Override
    public List<Map<String, Object>> getLegalCaseSource(String start, String end, Long regionid,Integer recType) {
        UnitInfo unit = unitInfoMapper.selectByPrimaryKey(regionid == null?1:regionid);
        return feignClientForce.getLegalCaseSource(start,end,unit.getUnitCode(),recType);
    }

    @Override
    public Map<String, Object> getLegalCaseRegion(String start, String end, Long regionid, Integer recType) {
        logger.debug("区域->");
        UnitInfo unit = unitInfoMapper.selectByPrimaryKey(regionid == null?1:regionid);
        List<Map<String, Object>> unitInfos =  feignClientSystem.getUnitInfoForProvince(regionid == null?1:regionid);
        List<Map<String, Object>> domainList =  feignClientForce.getLegalCaseRegion(start, end, unit.getUnitCode(),unit.getRegionCode(),recType);
        Map<String, Object> returnList = new HashMap<>();
        if ( unitInfos != null && domainList != null){
            logger.debug("区域->分组封装");
            unitInfos.addAll(domainList);
            List<Map<String, Object>> result = unitInfos.stream().collect(Collectors.groupingBy(e -> e.get("region_code")))
                    .entrySet().stream().map(e -> {
                        Map<String, Object> map = new HashMap<>();
                        map.put("regionid", e.getValue().get(0).get("unit_id"));
                        map.put("regionname", e.getValue().get(0).get("unit_name"));
                        map.put("seniorid", e.getValue().get(0).get("senior_id"));
                        map.put("regioncode",  regionIdFormat(e.getKey().toString()));
                        if (e.getValue().size()>1){
                            map.put("sumnum", e.getValue().get(1).get("count")==null?0:e.getValue().get(1).get("count"));
                        }else {
                            map.put("sumnum", 0);
                        }
                        return map;
                    }).collect(Collectors.toList());
            UnitInfo unitInfo = getRegionInfo(unit.getRegionCode());
            //封装返回格式
            final int[] i = {0};
            result.forEach(sun -> {
                i[0] += Integer.parseInt(sun.get("sumnum")==null?"0":sun.get("sumnum").toString());
            });
            Map<String, Object> statMap = new HashMap<>();
            Map<String, Object> regionMap = new HashMap<>();
            regionMap.put("regionid", unitInfo.getUnitId());
            regionMap.put("regioncode", regionIdFormat(unitInfo.getRegionCode()));
            regionMap.put("regionname", unitInfo.getUnitName());
            regionMap.put("sumnum", i[0]);
            regionMap.put("seniorid", unitInfo.getSeniorId());
            statMap.put("region", regionMap);
            statMap.put("children", result);
            returnList.put("stat", statMap);
        }
        return returnList;
    }

    @Override
    public List<Map<String, Object>> getLegalCaseDomain(String start, String end, Long regionid, Integer recType, Integer num) {
        UnitInfo unit = unitInfoMapper.selectByPrimaryKey(regionid == null?1:regionid);
        return feignClientForce.getLegalCaseDomain(start,end,unit.getUnitCode(),recType,num);
    }

    @Override
    public Map<String, Object> getLegalCaseGeneral(String start, String end ,Long regionid) {
        UnitInfo unit = unitInfoMapper.selectByPrimaryKey(regionid == null?1:regionid);
        return feignClientForce.getLegalCaseGeneral(start,end ,unit.getUnitCode());
    }

    @Override
    public List<Map<String, Object>> getLawCaseTop5(String start, String end, Long regionid, Integer recType) {
        UnitInfo unit = unitInfoMapper.selectByPrimaryKey(regionid == null?1:regionid);
        return feignClientForce.getLawCaseTop5(start,end,unit.getUnitCode(),recType);
    }

    @Override
    public List<Map<String, Object>> getLawCaseTop(String start, String end, Long regionid, Integer num) {
        UnitInfo unit = unitInfoMapper.selectByPrimaryKey(regionid == null?1:regionid);
        return feignClientForce.getLawCaseTop(start,end,unit.getUnitCode(),num);
    }

    @Override
    public List<Map<String, Object>> getLawUseStat(String start, String end, Long regionid) {
        UnitInfo unit = unitInfoMapper.selectByPrimaryKey(regionid == null?1:regionid);
        return feignClientForce.getLawUseStat(start,end,unit.getUnitCode());
    }

    @Override
    public List<Map<String, Object>> getCauseUseStat(String start, String end, Long regionid, String lawID) {
        UnitInfo unit = unitInfoMapper.selectByPrimaryKey(regionid == null?1:regionid);
        return feignClientForce.getCauseUseStat(start,end,unit.getUnitCode(),lawID);
    }

    @Override
    public List<Map<String, Object>> getForceByRegionId(String start, String end, Long regionid, Integer recType) {
        UnitInfo unit = unitInfoMapper.selectByPrimaryKey(regionid == null?1:regionid);
        return feignClientForce.getForceByRegionId(start,end,unit.getUnitCode(),recType);
    }

    private UnitInfo getRegionInfo(String regionCode) {
        logger.debug("查询unitInfo");
        Example example = new Example(UnitInfo.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("regionCode", regionCode);
        criteria.andEqualTo("unitTypeId", 0);
        return unitInfoMapper.selectByExample(example).get(0);
    }
    private String regionIdFormat(String regionId) {
        int n = 6;
        if (StringUtils.isNotBlank(regionId) && regionId.length()<n){
            return regionId+String.format("%1$0"+(n-regionId.length())+"d",0);
        }
        return regionId;
    }
}
